//
// Created by Administrator on 2021/8/13.
// line interpolate, bezier interpolate and spline
//

#ifndef OPENGLLEARN_MATH_H
#define OPENGLLEARN_MATH_H

#include "Common.h"

template<typename T>
inline T Lerp(const T& a, const T& b, float t)
{
    return a + t * (b - a);
}

template<typename T>
inline T QuadraticBezier(const T& a, const T& b, const T& c, float t)
{
    T d = Lerp(a, b, t);
    T e = Lerp(b, c, t);
    return Lerp(d, e, t);
}

template<typename T>
inline T CubicBezier(const T& a, const T& b, const T& c, const T& d, float t)
{
    T e = Lerp(a, b, t);
    T f = Lerp(b, c, t);
    T g = Lerp(c, d, t);
    return QuadraticBezierInterpolate(e, f, g, t);
}

template<typename T>
inline T QuinticBezier(const T& a, const T& b, const T& c, const T& d, const T e, float t)
{
    T f = Lerp(a, b, t);
    T g = Lerp(b, c, t);
    T h = Lerp(c, d, t);
    T i = Lerp(d, e, t);
    return CubicBezier(f, g, h, i, t);
}

template<typename T>
T CubicBSpline10(const T cp[], float t)
{
    if(t <= 0.0f)
    {
        return cp[0];
    }
    else if(t >= 1.0f)
    {
        return cp[9];
    }

    float s = t * 3.0f;
    int i = int(s);
    float f = t - i;

    T a = cp[i * 3];
    T b = cp[i * 3 + 1];
    T c = cp[i * 3 + 2];
    T d = cp[i * 3 + 3];
    return CubicBezier(a, b, c, d, f);
}

#endif //OPENGLLEARN_MATH_H
